package com.relax.mybatis.encrypt.algorithm;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import com.relax.mybatis.constant.EncryptConstants;

/**
 * 
 * @author relax
 * @date 2022/07/05
 * @desc AES加密
 */
public class AES {

    public static final String KEY_ALGORITHM = "AES";
    public static final String ALGORITHM = "AES/ECB/PKCS5Padding";

    private AES() {}

    public static SecretKeySpec generateMySQLAESKey(String key) {
        byte[] bytes = new byte[16];
        byte i = 0;
        for (byte b : key.getBytes(EncryptConstants.DEFAULT_CHARSET))
            bytes[i++ % 16] ^= b;
        return new SecretKeySpec(bytes, KEY_ALGORITHM);
    }

    public static byte[] encrypt(byte[] data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, generateMySQLAESKey(key));
        return cipher.doFinal(data);
    }

    public static String encryptToBase64(String data, String key) throws Exception {
        return Base64.encodeToString(encrypt(data.getBytes(EncryptConstants.DEFAULT_CHARSET), key));
    }

    public static String encryptToHex(String data, String key) throws Exception {
        return Hex.encodeToString(encrypt(data.getBytes(EncryptConstants.DEFAULT_CHARSET), key));
    }

    public static byte[] decrypt(byte[] data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, generateMySQLAESKey(key));
        return cipher.doFinal(data);
    }

    public static String decryptFromBase64(String data, String key) throws Exception {
        return new String(decrypt(Base64.decode(data), key), EncryptConstants.DEFAULT_CHARSET);
    }

    public static String decryptFromHex(String data, String key) throws Exception {
        return new String(decrypt(Hex.decode(data), key), EncryptConstants.DEFAULT_CHARSET);
    }

}
